home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / Level 1 Extensions 29Sep94 / TextView.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  34.6 KB  |  1,208 lines  |  [TEXT/KAHL]

  1. /* TextView.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    System Dependency Library for Building Portable Software               */
  5. /*    Macintosh Version                                                      */
  6. /*    Written by Thomas R. Lawrence, 1993 - 1994.                            */
  7. /*                                                                           */
  8. /*    This file is Public Domain; it may be used for any purpose whatsoever  */
  9. /*    without restriction.                                                   */
  10. /*                                                                           */
  11. /*    This package is distributed in the hope that it will be useful,        */
  12. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  13. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   */
  14. /*                                                                           */
  15. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  16. /*                                                                           */
  17. /*****************************************************************************/
  18.  
  19. #include "MiscInfo.h"
  20. #include "Audit.h"
  21. #include "Debug.h"
  22. #include "Definitions.h"
  23.  
  24. #include "TextView.h"
  25. #include "Memory.h"
  26. #include "EventLoop.h"
  27. #include "TextStorage.h"
  28.  
  29.  
  30. /* width of the edit area in pixels */
  31. #define HARDCODEDMAXWIDTH (5000)
  32.  
  33.  
  34. struct TextViewRec
  35.     {
  36.         TextStorageRec*            Storage;
  37.         WinType*                        Window;
  38.         OrdType                            X;
  39.         OrdType                            Y;
  40.         OrdType                            Width;
  41.         OrdType                            Height;
  42.         FontType                        FontID;
  43.         FontSizeType                FontSize;
  44.         OrdType                            LineHeight;
  45.         long                                CurrentTopLine;
  46.         OrdType                            PixelIndent;
  47.         long                                SpacesPerTab;
  48.         long                                SelectStartLine;
  49.         long                                SelectStartChar;
  50.         long                                SelectEndLine;
  51.         long                                SelectEndCharPlusOne;
  52.         MyBoolean                        CursorEnabledFlag;
  53.         MyBoolean                        CursorDrawnFlag;
  54.         double                            LastCursorFlashTime;
  55.     };
  56.  
  57.  
  58. /* create a new text view object */
  59. TextViewRec*            NewTextView(WinType* Window, OrdType X, OrdType Y,
  60.                                         OrdType Width, OrdType Height, long SpacesPerTab,
  61.                                         FontType Font, FontSizeType PointSize)
  62.     {
  63.         TextViewRec*        View;
  64.  
  65.         View = (TextViewRec*)AllocPtrCanFail(sizeof(TextViewRec),"TextViewRec");
  66.         if (View == NIL)
  67.             {
  68.              MemOut1:
  69.                 return NIL;
  70.             }
  71.         View->Storage = NewTextStorage();
  72.         if (View->Storage == NIL)
  73.             {
  74.              MemOut2:
  75.                 ReleasePtr((char*)View);
  76.                 goto MemOut1;
  77.             }
  78.         View->Window = Window;
  79.         View->X = X;
  80.         View->Y = Y;
  81.         View->Width = Width;
  82.         View->Height = Height;
  83.         View->FontID = Font;
  84.         View->FontSize = PointSize;
  85.         View->LineHeight = GetFontHeight(Font,PointSize);
  86.         View->CurrentTopLine = 0;
  87.         View->PixelIndent = 0;
  88.         View->SpacesPerTab = SpacesPerTab;
  89.         View->SelectStartLine = 0;
  90.         View->SelectStartChar = 0;
  91.         View->SelectEndLine = 0;
  92.         View->SelectEndCharPlusOne = 0;
  93.         View->CursorEnabledFlag = False;
  94.         View->CursorDrawnFlag = True;
  95.         View->LastCursorFlashTime = ReadTimer();
  96.         TextViewFullRedraw(View);
  97.         return View;
  98.     }
  99.  
  100.  
  101. /* dispose the text view object and all data it contains */
  102. void                            DisposeTextView(TextViewRec* View)
  103.     {
  104.         DisposeTextStorage(View->Storage);
  105.         ReleasePtr((char*)View);
  106.     }
  107.  
  108.  
  109. /* find out where the text view object is located on the screen */
  110. OrdType                        GetTextViewXLoc(TextViewRec* View)
  111.     {
  112.         CheckPtrExistence(View);
  113.         return View->X;
  114.     }
  115.  
  116.  
  117. /* find out where the text view object is located on the screen */
  118. OrdType                        GetTextViewYLoc(TextViewRec* View)
  119.     {
  120.         CheckPtrExistence(View);
  121.         return View->Y;
  122.     }
  123.  
  124.  
  125. /* find out where the text view object is located on the screen */
  126. OrdType                        GetTextViewWidth(TextViewRec* View)
  127.     {
  128.         CheckPtrExistence(View);
  129.         return View->Width;
  130.     }
  131.  
  132.  
  133. /* find out where the text view object is located on the screen */
  134. OrdType                        GetTextViewHeight(TextViewRec* View)
  135.     {
  136.         CheckPtrExistence(View);
  137.         return View->Height;
  138.     }
  139.  
  140.  
  141. /* find out what font the text is being displayed in */
  142. FontType                    GetTextViewFont(TextViewRec* View)
  143.     {
  144.         CheckPtrExistence(View);
  145.         return View->FontID;
  146.     }
  147.  
  148.  
  149. /* find out what font the text is being displayed in */
  150. FontSizeType            GetTextViewPointSize(TextViewRec* View)
  151.     {
  152.         CheckPtrExistence(View);
  153.         return View->FontSize;
  154.     }
  155.  
  156.  
  157. /* find out how many spaces are displayed for each tab */
  158. long                            GetTextViewSpacesPerTab(TextViewRec* View)
  159.     {
  160.         CheckPtrExistence(View);
  161.         return View->SpacesPerTab;
  162.     }
  163.  
  164.  
  165. /* find out what the index of the top line on the display is */
  166. long                            GetTextViewTopLine(TextViewRec* View)
  167.     {
  168.         CheckPtrExistence(View);
  169.         return View->CurrentTopLine;
  170.     }
  171.  
  172.  
  173. /* find out what the pixel position of the leftmost character displayed is */
  174. OrdType                        GetTextViewPixelIndent(TextViewRec* View)
  175.     {
  176.         CheckPtrExistence(View);
  177.         return View->PixelIndent;
  178.     }
  179.  
  180.  
  181. /* returns True if the selection contains more than 0 characters */
  182. MyBoolean                    TextViewIsThereValidSelection(TextViewRec* View)
  183.     {
  184.         CheckPtrExistence(View);
  185.         return (View->SelectStartLine != View->SelectEndLine)
  186.             || (View->SelectStartChar != View->SelectEndCharPlusOne);
  187.     }
  188.  
  189.  
  190. /* get the index of the starting line of the selection */
  191. long                            GetTextViewSelectStartLine(TextViewRec* View)
  192.     {
  193.         CheckPtrExistence(View);
  194.         return View->SelectStartLine;
  195.     }
  196.  
  197.  
  198. /* get the index of the last line of the selection */
  199. long                            GetTextViewSelectEndLine(TextViewRec* View)
  200.     {
  201.         CheckPtrExistence(View);
  202.         return View->SelectEndLine;
  203.     }
  204.  
  205.  
  206. /* get the index of the starting character of the selection */
  207. long                            GetTextViewSelectStartChar(TextViewRec* View)
  208.     {
  209.         CheckPtrExistence(View);
  210.         return View->SelectStartChar;
  211.     }
  212.  
  213.  
  214. /* get the index of the character after the end of the selection.  if the starting */
  215. /* line == ending line, and starting char == last char + 1, then there is no */
  216. /* selection, but instead an insertion point */
  217. long                            GetTextViewSelectEndCharPlusOne(TextViewRec* View)
  218.     {
  219.         CheckPtrExistence(View);
  220.         return View->SelectEndCharPlusOne;
  221.     }
  222.  
  223.  
  224. /* find out if display of inverted selection text is enabled */
  225. MyBoolean                    TextViewIsShowSelectionEnabled(TextViewRec* View)
  226.     {
  227.         CheckPtrExistence(View);
  228.         return View->CursorEnabledFlag;
  229.     }
  230.  
  231.  
  232. /* find out if any changes have been made to the text view object since */
  233. /* the last call to TextViewHasBeenSaved */
  234. MyBoolean                    TextViewDoesItNeedToBeSaved(TextViewRec* View)
  235.     {
  236.         CheckPtrExistence(View);
  237.         return TextStorageHasDataChanged(View->Storage);
  238.     }
  239.  
  240.  
  241. /* see if the specified position is within the text view box */
  242. MyBoolean                    TextViewHitTest(TextViewRec* View, OrdType X, OrdType Y)
  243.     {
  244.         CheckPtrExistence(View);
  245.         return (X >= View->X) && (Y >= View->Y) && (X < View->X + View->Width)
  246.             && (Y < View->Y + View->Height);
  247.     }
  248.  
  249.  
  250. /* find out the total number of lines in the text view box */
  251. long                            GetTextViewNumLines(TextViewRec* View)
  252.     {
  253.         CheckPtrExistence(View);
  254.         return TextStorageGetLineCount(View->Storage);
  255.     }
  256.  
  257.  
  258. /* find out how many characters the specified line contains */
  259. long                            GetTextViewLineLength(TextViewRec* View, long LineIndex)
  260.     {
  261.         CheckPtrExistence(View);
  262.         return TextStorageGetLineLength(View->Storage,LineIndex);
  263.     }
  264.  
  265.  
  266. /* get the height of a line of text (font height) */
  267. OrdType                        GetTextViewLineHeight(TextViewRec* View)
  268.     {
  269.         CheckPtrExistence(View);
  270.         return View->LineHeight;
  271.     }
  272.  
  273.  
  274. /* change where in the window the text view box is located */
  275. void                            SetTextViewPosition(TextViewRec* View, OrdType X, OrdType Y,
  276.                                         OrdType Width, OrdType Height)
  277.     {
  278.         CheckPtrExistence(View);
  279.         View->X = X;
  280.         View->Y = Y;
  281.         View->Width = Width;
  282.         View->Height = Height;
  283.         TextViewFullRedraw(View);
  284.     }
  285.  
  286.  
  287. /* change the font being used to display the text */
  288. void                            SetTextViewFontStuff(TextViewRec* View, FontType Font,
  289.                                         FontSizeType Size)
  290.     {
  291.         CheckPtrExistence(View);
  292.         View->FontID = Font;
  293.         View->FontSize = Size;
  294.         View->LineHeight = GetFontHeight(Font,Size);
  295.         TextViewFullRedraw(View);
  296.     }
  297.  
  298.  
  299. /* change the number of spaces displayed for each tab */
  300. void                            SetTextViewTabSize(TextViewRec* View, long SpacesPerTab)
  301.     {
  302.         CheckPtrExistence(View);
  303.         View->SpacesPerTab = SpacesPerTab;
  304.         TextViewFullRedraw(View);
  305.     }
  306.  
  307.  
  308. /* set the index of the top line being displayed in the text box */
  309. void                            SetTextViewTopLine(TextViewRec* View, long NewTopLine)
  310.     {
  311.         long                NumLinesToShiftBy;
  312.  
  313.         CheckPtrExistence(View);
  314.         if (NewTopLine > GetTextViewNumLines(View) - TextViewNumVisibleLines(View) + 1)
  315.             {
  316.                 NewTopLine = GetTextViewNumLines(View) - TextViewNumVisibleLines(View) + 1;
  317.             }
  318.         if (NewTopLine < 0)
  319.             {
  320.                 NewTopLine = 0;
  321.             }
  322.         NumLinesToShiftBy = View->CurrentTopLine - NewTopLine;
  323.         View->CurrentTopLine = NewTopLine;
  324.         /* positive == scroll down; negative == scroll up */
  325.         if ((NumLinesToShiftBy > TextViewNumVisibleLines(View))
  326.             || (- NumLinesToShiftBy > TextViewNumVisibleLines(View)))
  327.             {
  328.                 TextViewFullRedraw(View);
  329.             }
  330.          else
  331.             {
  332.                 SetClipRect(View->Window,View->X,View->Y,View->Width,View->Height);
  333.                 ScrollArea(View->Window,View->X,View->Y,View->Width,
  334.                     View->Height,0,NumLinesToShiftBy * View->LineHeight);
  335.                 if (NumLinesToShiftBy > 0)
  336.                     {
  337.                         /* scrolled down, opening new lines at top */
  338.                         TextViewRedrawRange(View,NewTopLine,NewTopLine + NumLinesToShiftBy);
  339.                     }
  340.                  else
  341.                     {
  342.                         /* scrolled up, opening new lines at bottom */
  343.                         TextViewRedrawRange(View,NewTopLine + (TextViewNumVisibleLines(View) - 1)
  344.                             + NumLinesToShiftBy/*which is negative*/,
  345.                             NewTopLine + (TextViewNumVisibleLines(View) - 1));
  346.                     }
  347.             }
  348.     }
  349.  
  350.  
  351. /* set the index of the leftmost character in the text edit box */
  352. void                            SetTextViewPixelIndent(TextViewRec* View, OrdType NewPixelIndent)
  353.     {
  354.         long                OldPixelIndent;
  355.         long                VirtualWindowWidth;
  356.  
  357.         /* this routine could be improved; but don't forget to SetClipRect! */
  358.         CheckPtrExistence(View);
  359.         OldPixelIndent = View->PixelIndent;
  360.         VirtualWindowWidth = TextViewGetVirtualWindowWidth(View);
  361.         if (NewPixelIndent > VirtualWindowWidth - View->Width)
  362.             {
  363.                 NewPixelIndent = VirtualWindowWidth - View->Width;
  364.             }
  365.         if (NewPixelIndent < 0)
  366.             {
  367.                 NewPixelIndent = 0;
  368.             }
  369.         if (OldPixelIndent != NewPixelIndent)
  370.             {
  371.                 View->PixelIndent = NewPixelIndent;
  372.                 TextViewFullRedraw(View);
  373.             }
  374.     }
  375.  
  376.  
  377. /* set the selection to the specified area */
  378. void                            SetTextViewSelection(TextViewRec* View, long StartLine,
  379.                                         long StartChar, long EndLine, long EndCharPlusOne)
  380.     {
  381.         long                OldSelectStartLine;
  382.         long                OldSelectEndLine;
  383.  
  384.         CheckPtrExistence(View);
  385.         ERROR((StartLine > EndLine) || ((StartLine == EndLine)
  386.             && (StartChar > EndCharPlusOne)),
  387.             PRERR(AllowResume,"SetTextViewSelection:  Start line after end line"));
  388.         if (StartLine > GetTextViewNumLines(View) - 1)
  389.             {
  390.                 StartLine = GetTextViewNumLines(View) - 1;
  391.                 StartChar = GetTextViewLineLength(View,StartLine);
  392.             }
  393.         if (EndLine > GetTextViewNumLines(View) - 1)
  394.             {
  395.                 EndLine = GetTextViewNumLines(View) - 1;
  396.                 EndCharPlusOne = GetTextViewLineLength(View,EndLine);
  397.             }
  398.         if (StartChar > GetTextViewLineLength(View,StartLine))
  399.             {
  400.                 StartChar = GetTextViewLineLength(View,StartLine);
  401.             }
  402.         if (EndCharPlusOne > GetTextViewLineLength(View,EndLine))
  403.             {
  404.                 EndCharPlusOne = GetTextViewLineLength(View,EndLine);
  405.             }
  406.         if ((StartLine == EndLine) && (StartChar == EndCharPlusOne))
  407.             {
  408.                 /* make an insertion point always show up right away in it's new location */
  409.                 View->CursorDrawnFlag = True;
  410.                 View->LastCursorFlashTime = ReadTimer();
  411.             }
  412.         OldSelectStartLine = View->SelectStartLine;
  413.         OldSelectEndLine = View->SelectEndLine;
  414.         View->SelectStartLine = StartLine;
  415.         View->SelectEndLine = EndLine;
  416.         View->SelectStartChar = StartChar;
  417.         View->SelectEndCharPlusOne = EndCharPlusOne;
  418.         if ((StartLine > OldSelectEndLine) || (EndLine < OldSelectStartLine))
  419.             {
  420.                 /* old and new selection ranges are disjoint */
  421.                 TextViewRedrawRange(View,OldSelectStartLine,OldSelectEndLine);
  422.                 TextViewRedrawRange(View,StartLine,EndLine);
  423.             }
  424.         else if ((StartLine >= OldSelectStartLine) && (StartLine <= OldSelectEndLine))
  425.             {
  426.                 long                Begin;
  427.                 long                End;
  428.  
  429.                 /* |  old selection   |.......|  */
  430.                 /*    |   new selection   | */
  431.                 /* we want to draw the line that overlaps due to partial selection */
  432.                 TextViewRedrawRange(View,OldSelectStartLine,StartLine);
  433.                 if (OldSelectEndLine < EndLine)
  434.                     {
  435.                         Begin = OldSelectEndLine;
  436.                         End = EndLine;
  437.                     }
  438.                  else
  439.                     {
  440.                         Begin = EndLine;
  441.                         End = OldSelectEndLine;
  442.                     }
  443.                 TextViewRedrawRange(View,Begin,End);
  444.             }
  445.         else if ((OldSelectStartLine >= StartLine) && (OldSelectStartLine <= EndLine))
  446.             {
  447.                 long                Begin;
  448.                 long                End;
  449.  
  450.                 /*    |   old selection  | */
  451.                 /* |  new selection   |.....| */
  452.                 TextViewRedrawRange(View,StartLine,OldSelectStartLine);
  453.                 if (OldSelectEndLine < EndLine)
  454.                     {
  455.                         Begin = OldSelectEndLine;
  456.                         End = EndLine;
  457.                     }
  458.                  else
  459.                     {
  460.                         Begin = EndLine;
  461.                         End = OldSelectEndLine;
  462.                     }
  463.                 TextViewRedrawRange(View,Begin,End);
  464.             }
  465.         else
  466.             {
  467.                 long                Minimum;
  468.                 long                Maximum;
  469.  
  470.                 /* we don't know what the hell is going on */
  471.                 if (OldSelectStartLine < StartLine)
  472.                     {
  473.                         Minimum = OldSelectStartLine;
  474.                     }
  475.                  else
  476.                     {
  477.                         Minimum = StartLine;
  478.                     }
  479.                 if (OldSelectEndLine > EndLine)
  480.                     {
  481.                         Maximum = OldSelectEndLine;
  482.                     }
  483.                  else
  484.                     {
  485.                         Maximum = EndLine;
  486.                     }
  487.                 TextViewRedrawRange(View,Minimum,Maximum);
  488.             }
  489.     }
  490.  
  491.  
  492. /* set the selection to an insertion point at the specified position */
  493. void                            SetTextViewInsertionPoint(TextViewRec* View, long Line, long Char)
  494.     {
  495.         CheckPtrExistence(View);
  496.         SetTextViewSelection(View,Line,Char,Line,Char);
  497.     }
  498.  
  499.  
  500. /* enable the display of inverted selected text */
  501. void                            EnableTextViewSelection(TextViewRec* View)
  502.     {
  503.         CheckPtrExistence(View);
  504.         View->CursorEnabledFlag = True;
  505.         TextViewRedrawRange(View,View->SelectStartLine,View->SelectEndLine);
  506.     }
  507.  
  508.  
  509. /* disable the display of inverted selected text */
  510. void                            DisableTextViewSelection(TextViewRec* View)
  511.     {
  512.         CheckPtrExistence(View);
  513.         View->CursorEnabledFlag = False;
  514.         TextViewRedrawRange(View,View->SelectStartLine,View->SelectEndLine);
  515.     }
  516.  
  517.  
  518. /* indicate that any changes to the text have been recognized */
  519. void                            TextViewHasBeenSaved(TextViewRec* View)
  520.     {
  521.         CheckPtrExistence(View);
  522.         TextStorageDataIsUpToDate(View->Storage);
  523.     }
  524.  
  525.  
  526. /* break the specified line at the specified character index.  this is used */
  527. /* for when they hit carriage return in the middle of a line */
  528. MyBoolean                    TextViewBreakLine(TextViewRec* View, long LineIndex, long CharIndex)
  529.     {
  530.         MyBoolean                ReturnValue;
  531.  
  532.         CheckPtrExistence(View);
  533.         ReturnValue = TextStorageBreakLine(View->Storage,LineIndex,CharIndex);
  534.         TextViewRedrawRange(View,LineIndex,TextStorageGetLineCount(View->Storage)
  535.             + TextViewNumVisibleLines(View));
  536.         return ReturnValue;
  537.     }
  538.  
  539.  
  540. /* concatenate the line after the specified line onto the end of the */
  541. /* specified line.  Used for hitting delete at the beginning of a line */
  542. MyBoolean                    TextViewFoldLines(TextViewRec* View, long LineIndex)
  543.     {
  544.         MyBoolean                ReturnValue;
  545.  
  546.         CheckPtrExistence(View);
  547.         ReturnValue = TextStorageFoldLines(View->Storage,LineIndex);
  548.         TextViewRedrawRange(View,LineIndex,TextStorageGetLineCount(View->Storage)
  549.             + TextViewNumVisibleLines(View) + 1);
  550.         return ReturnValue;
  551.     }
  552.  
  553.  
  554. /* do a complete redraw of the text view box */
  555. void                            TextViewFullRedraw(TextViewRec* View)
  556.     {
  557.         long                Scan;
  558.         long                Limit;
  559.  
  560.         CheckPtrExistence(View);
  561.         Limit = View->CurrentTopLine + TextViewNumVisibleLines(View);
  562.         for (Scan = View->CurrentTopLine; Scan < Limit; Scan += 1)
  563.             {
  564.                 TextViewRedrawLine(View,Scan);
  565.             }
  566.     }
  567.  
  568.  
  569. /* redraw the specified line */
  570. void                            TextViewRedrawLine(TextViewRec* View, long LineIndex)
  571.     {
  572.         OrdType            YOffset;
  573.         char*                Line;
  574.  
  575.         CheckPtrExistence(View);
  576.         if ((LineIndex < View->CurrentTopLine)
  577.             || (LineIndex >= View->CurrentTopLine + TextViewNumVisibleLines(View)))
  578.             {
  579.                 /* don't draw lines that aren't on screen */
  580.                 return;
  581.             }
  582.         YOffset = (LineIndex - View->CurrentTopLine) * View->LineHeight;
  583.         if (!IsRectVisible(View->Window,View->X,View->Y + YOffset,
  584.             View->Width,View->LineHeight))
  585.             {
  586.                 /* don't bother redrawing if the line isn't visible */
  587.                 return;
  588.             }
  589.         SetClipRect(View->Window,View->X,View->Y,View->Width,View->Height);
  590.         if ((LineIndex < 0) || (LineIndex >= TextStorageGetLineCount(View->Storage)))
  591.             {
  592.                 /* degenerate blank line draw routine for nonexistent lines */
  593.              NopePoint:
  594.                 DrawBoxErase(View->Window,View->X,View->Y + YOffset,
  595.                     View->Width,View->LineHeight);
  596.                 return;
  597.             }
  598.         Line = GetTextViewSpaceFromTabLine(View,LineIndex);
  599.         if (Line == NIL)
  600.             {
  601.                 goto NopePoint;
  602.             }
  603.         if ((LineIndex < View->SelectStartLine) || (LineIndex > View->SelectEndLine)
  604.             || !View->CursorEnabledFlag)
  605.             {
  606.                 /* normal draw -- no part of the line is selected */
  607.                 DrawTextLine(View->Window,View->FontID,View->FontSize,
  608.                     &(Line[0]),PtrSize(Line),View->X - View->PixelIndent,
  609.                     View->Y + YOffset,ePlain);
  610.                 DrawBoxErase(View->Window,View->X - View->PixelIndent
  611.                     + LengthOfText(View->FontID,View->FontSize,&(Line[0]),
  612.                     PtrSize(Line),ePlain),View->Y + YOffset,
  613.                     View->Width + View->PixelIndent,View->LineHeight);
  614.             }
  615.          else
  616.             {
  617.                 if ((View->SelectStartLine == View->SelectEndLine)
  618.                     && (View->SelectStartChar == View->SelectEndCharPlusOne))
  619.                     {
  620.                         /* it's just an insertion point */
  621.                         DrawTextLine(View->Window,View->FontID,View->FontSize,
  622.                             &(Line[0]),PtrSize(Line),View->X - View->PixelIndent,
  623.                             View->Y + YOffset,ePlain);
  624.                         /* erase white space at end of line */
  625.                         DrawBoxErase(View->Window,View->X - View->PixelIndent
  626.                             + LengthOfText(View->FontID,View->FontSize,&(Line[0]),
  627.                             PtrSize(Line),ePlain),View->Y + YOffset,
  628.                             View->Width + View->PixelIndent,View->LineHeight);
  629.                         if (View->CursorDrawnFlag)
  630.                             {
  631.                                 DrawLine(View->Window,eBlack,View->X - View->PixelIndent
  632.                                     + TextViewScreenXFromCharIndex(View,LineIndex,
  633.                                     View->SelectStartChar),
  634.                                     View->Y + YOffset,0,View->LineHeight - 1);
  635.                             }
  636.                     }
  637.                  else
  638.                     {
  639.                         long                SelectStartColumn;
  640.                         long                SelectEndColumnPlusOne;
  641.  
  642.                         /* real live selection */
  643.                         /* since SelectStart/End deals in chars, but we deal in columns */
  644.                         /* (i.e. tabs expanded), we have to do a conversion: */
  645.                         SelectStartColumn = TextViewCalculateColumnFromCharIndex(View,
  646.                             View->SelectStartLine,View->SelectStartChar);
  647.                         SelectEndColumnPlusOne = TextViewCalculateColumnFromCharIndex(View,
  648.                             View->SelectEndLine,View->SelectEndCharPlusOne);
  649.                         if ((View->SelectStartLine == LineIndex)
  650.                             && (View->SelectEndLine == LineIndex))
  651.                             {
  652.                                 OrdType                StepWidth;
  653.  
  654.                                 /* it's all on the same line, but not an insertion point */
  655.                                 /* draw leading white area */
  656.                                 DrawTextLine(View->Window,View->FontID,View->FontSize,
  657.                                     &(Line[0]),SelectStartColumn,
  658.                                     View->X - View->PixelIndent,View->Y + YOffset,ePlain);
  659.                                 /* find width of leading white area */
  660.                                 StepWidth = LengthOfText(View->FontID,View->FontSize,
  661.                                     &(Line[0]),SelectStartColumn,ePlain);
  662.                                 /* draw middle black area */
  663.                                 InvertedTextLine(View->Window,View->FontID,View->FontSize,
  664.                                     &(Line[SelectStartColumn]),
  665.                                     SelectEndColumnPlusOne - SelectStartColumn,
  666.                                     View->X - View->PixelIndent + StepWidth,
  667.                                     View->Y + YOffset,ePlain);
  668.                                 /* find width of middle black area */
  669.                                 StepWidth += LengthOfText(View->FontID,View->FontSize,
  670.                                     &(Line[SelectStartColumn]),
  671.                                     SelectEndColumnPlusOne - SelectStartColumn,ePlain);
  672.                                 /* draw trailing white area */
  673.                                 DrawTextLine(View->Window,View->FontID,View->FontSize,
  674.                                     &(Line[SelectEndColumnPlusOne]),
  675.                                     PtrSize(Line) - SelectEndColumnPlusOne,
  676.                                     View->X - View->PixelIndent + StepWidth,
  677.                                     View->Y + YOffset,ePlain);
  678.                                 /* calculate start of white space after eoln */
  679.                                 StepWidth += LengthOfText(View->FontID,View->FontSize,
  680.                                     &(Line[SelectEndColumnPlusOne]),
  681.                                     PtrSize(Line) - SelectEndColumnPlusOne,ePlain);
  682.                                 /* erase white space after end of line */
  683.                                 DrawBoxErase(View->Window,View->X - View->PixelIndent
  684.                                     + StepWidth,View->Y + YOffset,View->Width
  685.                                     + View->PixelIndent,View->LineHeight);
  686.                             }
  687.                         else if ((View->SelectStartLine < LineIndex)
  688.                             && (View->SelectEndLine > LineIndex))
  689.                             {
  690.                                 /* whole line is inverted */
  691.                                 InvertedTextLine(View->Window,View->FontID,View->FontSize,
  692.                                     &(Line[0]),PtrSize(Line),View->X - View->PixelIndent,
  693.                                     View->Y + YOffset,ePlain);
  694.                                 DrawBoxPaint(View->Window,eBlack,View->X - View->PixelIndent
  695.                                     + LengthOfText(View->FontID,View->FontSize,&(Line[0]),
  696.                                     PtrSize(Line),ePlain),View->Y + YOffset,
  697.                                     View->Width + View->PixelIndent,View->LineHeight);
  698.                             }
  699.                         else if (View->SelectStartLine == LineIndex)
  700.                             {
  701.                                 OrdType                StepWidth;
  702.  
  703.                                 /* end of line is inverted */
  704.                                 /* draw leading white area */
  705.                                 DrawTextLine(View->Window,View->FontID,View->FontSize,
  706.                                     &(Line[0]),SelectStartColumn,
  707.                                     View->X - View->PixelIndent,View->Y + YOffset,ePlain);
  708.                                 /* find width of leading white area */
  709.                                 StepWidth = LengthOfText(View->FontID,View->FontSize,
  710.                                     &(Line[0]),SelectStartColumn,ePlain);
  711.                                 /* draw ending black area */
  712.                                 InvertedTextLine(View->Window,View->FontID,View->FontSize,
  713.                                     &(Line[SelectStartColumn]),
  714.                                     PtrSize(Line) - SelectStartColumn,
  715.                                     View->X - View->PixelIndent + StepWidth,
  716.                                     View->Y + YOffset,ePlain);
  717.                                 /* find width of ending black area */
  718.                                 StepWidth += LengthOfText(View->FontID,View->FontSize,
  719.                                     &(Line[SelectStartColumn]),
  720.                                     PtrSize(Line) - SelectStartColumn,ePlain);
  721.                                 /* draw black space after end of line */
  722.                                 DrawBoxPaint(View->Window,eBlack,View->X - View->PixelIndent
  723.                                     + StepWidth,View->Y + YOffset,View->Width
  724.                                     + View->PixelIndent,View->LineHeight);
  725.                             }
  726.                         else if (View->SelectEndLine == LineIndex)
  727.                             {
  728.                                 OrdType                StepWidth;
  729.  
  730.                                 /* start of line is inverted */
  731.                                 /* draw leading black area */
  732.                                 InvertedTextLine(View->Window,View->FontID,View->FontSize,
  733.                                     &(Line[0]),SelectEndColumnPlusOne,
  734.                                     View->X - View->PixelIndent,View->Y + YOffset,ePlain);
  735.                                 /* find width of leading black area */
  736.                                 StepWidth = LengthOfText(View->FontID,View->FontSize,
  737.                                     &(Line[0]),SelectEndColumnPlusOne,ePlain);
  738.                                 /* draw ending white area */
  739.                                 DrawTextLine(View->Window,View->FontID,View->FontSize,
  740.                                     &(Line[SelectEndColumnPlusOne]),
  741.                                     PtrSize(Line) - SelectEndColumnPlusOne,
  742.                                     View->X - View->PixelIndent + StepWidth,
  743.                                     View->Y + YOffset,ePlain);
  744.                                 /* find width of ending white area */
  745.                                 StepWidth += LengthOfText(View->FontID,View->FontSize,
  746.                                     &(Line[SelectEndColumnPlusOne]),
  747.                                     PtrSize(Line) - SelectEndColumnPlusOne,ePlain);
  748.                                 /* draw white space after end of line */
  749.                                 DrawBoxErase(View->Window,View->X - View->PixelIndent
  750.                                     + StepWidth,View->Y + YOffset,View->Width
  751.                                     + View->PixelIndent,View->LineHeight);
  752.                             }
  753.                         else
  754.                             {
  755.                                 EXECUTE(PRERR(AllowResume,
  756.                                     "Internal conditional hole in TextViewRedrawLine"));
  757.                             }
  758.                     }
  759.             }
  760.         ReleasePtr(Line);
  761.     }
  762.  
  763.  
  764. /* redraw a series of lines */
  765. void                            TextViewRedrawRange(TextViewRec* View, long StartLine, long EndLine)
  766.     {
  767.         long                Scan;
  768.  
  769.         for (Scan = StartLine; Scan <= EndLine; Scan += 1)
  770.             {
  771.                 TextViewRedrawLine(View,Scan);
  772.             }
  773.     }
  774.  
  775.  
  776. /* update the cursor.  this should be called every time there is an idle */
  777. /* event.  periodically, it will blink the insertion point state (if there */
  778. /* is no valid selection) */
  779. void                            TextViewUpdateCursor(TextViewRec* View)
  780.     {
  781.         CheckPtrExistence(View);
  782.         if (View->CursorEnabledFlag && !TextViewIsThereValidSelection(View)
  783.             && (TimerDifference(ReadTimer(),View->LastCursorFlashTime)
  784.                 > GetCursorBlinkRate()))
  785.             {
  786.                 View->CursorDrawnFlag = !View->CursorDrawnFlag;
  787.                 TextViewRedrawLine(View,View->SelectStartLine);
  788.                 View->LastCursorFlashTime = ReadTimer();
  789.             }
  790.     }
  791.  
  792.  
  793. /* find out the pixel index of the left edge of the specified character */
  794. OrdType                        TextViewScreenXFromCharIndex(TextViewRec* View, long LineIndex,
  795.                                         long CharIndex)
  796.     {
  797.         char*                    FixedLine;
  798.         OrdType                Indent;
  799.         long                    ColumnIndex;
  800.  
  801.         CheckPtrExistence(View);
  802.         FixedLine = GetTextViewSpaceFromTabLine(View,LineIndex);
  803.         if (FixedLine == NIL)
  804.             {
  805.                 return 0;
  806.             }
  807.         ColumnIndex = TextViewCalculateColumnFromCharIndex(View,LineIndex,CharIndex);
  808.         Indent = LengthOfText(View->FontID,View->FontSize,&(FixedLine[0]),
  809.             ColumnIndex,ePlain);
  810.         ReleasePtr(FixedLine);
  811.         return Indent;
  812.     }
  813.  
  814.  
  815. /* convert a pixel position into the nearest character */
  816. long                            TextViewCharIndexFromScreenX(TextViewRec* View, long LineIndex,
  817.                                         OrdType ScreenX)
  818.     {
  819.         char*                    Line;
  820.         long                    ColumnIndex;
  821.         long                    CharIndexLowBound;
  822.         long                    CharIndexHighBound;
  823.         long                    Scan;
  824.         long                    Limit;
  825.         OrdType                Length;
  826.  
  827.         CheckPtrExistence(View);
  828.         if ((LineIndex < 0) || (LineIndex >= GetTextViewNumLines(View)))
  829.             {
  830.                 return 0;
  831.             }
  832.         Line = GetTextViewSpaceFromTabLine(View,LineIndex);
  833.         if (Line == NIL)
  834.             {
  835.                 return 0;
  836.             }
  837.         Limit = PtrSize(Line);
  838.         Scan = 0;
  839.         Length = 0;
  840.         while (Scan < Limit)
  841.             {
  842.                 OrdType            Length2;
  843.                 OrdType            Center;
  844.  
  845.                 Length2 = LengthOfText(View->FontID,View->FontSize,&(Line[0]),
  846.                     Scan + 1,ePlain);
  847.                 Center = (Length + Length2) / 2;
  848.                 if (ScreenX <= Length2)
  849.                     {
  850.                         if (ScreenX - Center < 0)
  851.                             {
  852.                                 ColumnIndex = Scan;
  853.                                 goto OutPoint;
  854.                             }
  855.                          else
  856.                             {
  857.                                 ColumnIndex = Scan + 1;
  858.                             }
  859.                     }
  860.                 Scan += 1;
  861.                 Length = Length2;
  862.             }
  863.         ColumnIndex = Limit;
  864.         /* now we have the column index, with tabs expanded; we have to figure */
  865.         /* out what the character index is, with tabs left intact */
  866.      OutPoint:
  867.         CharIndexLowBound = 0;
  868.         CharIndexHighBound = ColumnIndex; /* tabs never reduce to FEWER spaces! */
  869.         /* test for convergence again... */
  870.         while (CharIndexLowBound < CharIndexHighBound)
  871.             {
  872.                 long                MidPoint;
  873.                 long                MidColumnIndex;
  874.  
  875.                 MidPoint = (CharIndexLowBound + CharIndexHighBound) / 2;
  876.                 MidColumnIndex = TextViewCalculateColumnFromCharIndex(View,LineIndex,MidPoint);
  877.                 if (MidColumnIndex < ColumnIndex)
  878.                     {
  879.                         if (CharIndexLowBound == MidPoint)
  880.                             {
  881.                                 CharIndexLowBound = MidPoint + 1;
  882.                             }
  883.                          else
  884.                             {
  885.                                 CharIndexLowBound = MidPoint;
  886.                             }
  887.                     }
  888.                 else if (MidColumnIndex > ColumnIndex)
  889.                     {
  890.                         CharIndexHighBound = MidPoint;
  891.                     }
  892.                 else /* they're the same */
  893.                     {
  894.                         CharIndexLowBound = MidPoint;
  895.                         CharIndexHighBound = MidPoint;
  896.                     }
  897.             }
  898.         ReleasePtr(Line);
  899.         return CharIndexLowBound;
  900.     }
  901.  
  902.  
  903. /* find out how many lines are visible on the screen */
  904. long                            TextViewNumVisibleLines(TextViewRec* View)
  905.     {
  906.         long                        Temp;
  907.  
  908.         CheckPtrExistence(View);
  909.         Temp = View->Height / View->LineHeight;
  910.         if ((View->Height % View->LineHeight) != 0)
  911.             {
  912.                 /* part of a line is visible */
  913.                 Temp += 1;
  914.             }
  915.         return Temp;
  916.     }
  917.  
  918.  
  919. /* get the width of the horizontal scrollable area */
  920. OrdType                        TextViewGetVirtualWindowWidth(TextViewRec* View)
  921.     {
  922. #if 0
  923.         /* this stuff doesn't quite work (too slow) so it's been commented out */
  924.         long                Scan;
  925.         long                Limit;
  926.         OrdType            CurrentMaxWidth;
  927.         long                LineCount;
  928.  
  929.         CheckPtrExistence(View);
  930.         Limit = View->CurrentTopLine + TextViewNumVisibleLines(View);
  931.         CurrentMaxWidth = View->Width;
  932.         LineCount = TextStorageGetLineCount(View->Storage);
  933.         if (Limit >= LineCount)
  934.             {
  935.                 Limit = LineCount - 1;
  936.             }
  937.         for (Scan = View->CurrentTopLine; Scan < Limit; Scan += 1)
  938.             {
  939.                 char*            Line;
  940.  
  941.                 Line = GetTextViewSpaceFromTabLine(View,Scan);
  942.                 if (Line != NIL)
  943.                     {
  944.                         OrdType            Length;
  945.  
  946.                         Length = LengthOfText(View->FontID,View->FontSize,&(Line[0]),
  947.                             PtrSize(Line),ePlain);
  948.                         if (CurrentMaxWidth < Length)
  949.                             {
  950.                                 CurrentMaxWidth = Length;
  951.                             }
  952.                         ReleasePtr(Line);
  953.                     }
  954.             }
  955.         if (CurrentMaxWidth > View->Width)
  956.             {
  957.                 /* make some space so that the cursor is visible */
  958.                 CurrentMaxWidth += 3;
  959.             }
  960.         return CurrentMaxWidth;
  961. #else
  962.         return HARDCODEDMAXWIDTH;
  963. #endif
  964.     }
  965.  
  966.  
  967. /* get a copy of the specified line */
  968. char*                            GetTextViewLine(TextViewRec* View, long LineIndex)
  969.     {
  970.         CheckPtrExistence(View);
  971.         return TextStorageGetLineCopy(View->Storage,LineIndex);
  972.     }
  973.  
  974.  
  975. /* get a copy of the specified line, but first convert all tabs to the */
  976. /* appropriate number of spaces */
  977. char*                            GetTextViewSpaceFromTabLine(TextViewRec* View, long LineIndex)
  978.     {
  979.         long                Length;
  980.         long                TotalExtraSpace;
  981.         char*                Temp2;
  982.         long                CharScan;
  983.         long                TargetIndex;
  984.         MyBoolean        TabsFound;
  985.         char*                BasePtr;
  986.  
  987.         CheckPtrExistence(View);
  988.         BasePtr = TextStorageGetActualLine(View->Storage,LineIndex);
  989.         Length = PtrSize(BasePtr);
  990.         TotalExtraSpace = 0;
  991.         TargetIndex = 0;
  992.         TabsFound = False;
  993.         for (CharScan = 0; CharScan < Length; CharScan += 1)
  994.             {
  995.                 if (BasePtr[CharScan] == 0x09)
  996.                     {
  997.                         TotalExtraSpace += View->SpacesPerTab
  998.                             - (TargetIndex % View->SpacesPerTab) - 1;
  999.                         TargetIndex += View->SpacesPerTab
  1000.                             - (TargetIndex % View->SpacesPerTab);
  1001.                         TabsFound = True;
  1002.                     }
  1003.                  else
  1004.                     {
  1005.                         TargetIndex += 1;
  1006.                     }
  1007.             }
  1008.         if ((TotalExtraSpace != 0) || TabsFound)
  1009.             {
  1010.                 TargetIndex = 0;
  1011.                 Temp2 = AllocPtrCanFail(Length + TotalExtraSpace,"TabExpandedLine");
  1012.                 if (Temp2 == NIL)
  1013.                     {
  1014.                         return NIL;
  1015.                     }
  1016.                 for (CharScan = 0; CharScan < Length; CharScan += 1)
  1017.                     {
  1018.                         if (BasePtr[CharScan] == 0x09)
  1019.                             {
  1020.                                 long                            Index;
  1021.  
  1022.                                 Index = View->SpacesPerTab - (TargetIndex % View->SpacesPerTab);
  1023.                                 while (Index > 0)
  1024.                                     {
  1025.                                         PRNGCHK(Temp2,&(Temp2[TargetIndex]),sizeof(char));
  1026.                                         Temp2[TargetIndex] = 0x20;
  1027.                                         TargetIndex += 1;
  1028.                                         Index -= 1;
  1029.                                     }
  1030.                             }
  1031.                          else
  1032.                             {
  1033.                                 PRNGCHK(Temp2,&(Temp2[TargetIndex]),sizeof(char));
  1034.                                 Temp2[TargetIndex] = BasePtr[CharScan];
  1035.                                 TargetIndex += 1;
  1036.                             }
  1037.                     }
  1038.                 ERROR(PtrSize(Temp2) != TargetIndex,PRERR(AllowResume,
  1039.                     "GetTextViewSpaceFromTabLine:  Internal error converting tabs to spaces"));
  1040.             }
  1041.          else
  1042.             {
  1043.                 Temp2 = AllocPtrCanFail(PtrSize(BasePtr),"TabExpandedLine");
  1044.                 if (Temp2 == NIL)
  1045.                     {
  1046.                         return NIL;
  1047.                     }
  1048.                 PRNGCHK(Temp2,&(Temp2[0]),PtrSize(BasePtr));
  1049.                 CopyData(BasePtr,Temp2,PtrSize(BasePtr));
  1050.             }
  1051.         return Temp2;
  1052.     }
  1053.  
  1054.  
  1055. /* given a character index, calculate where the corresponding position is */
  1056. /* when tabs have been converted into spaces */
  1057. long                            TextViewCalculateColumnFromCharIndex(TextViewRec* View,
  1058.                                         long LineIndex, long CharIndex)
  1059.     {
  1060.         long                CharScan;
  1061.         long                TargetIndex;
  1062.         char*                BasePtr;
  1063.  
  1064.         CheckPtrExistence(View);
  1065.         BasePtr = TextStorageGetActualLine(View->Storage,LineIndex);
  1066.         if (CharIndex > PtrSize(BasePtr))
  1067.             {
  1068.                 CharIndex = PtrSize(BasePtr);
  1069.             }
  1070.         ERROR((CharIndex < 0) || (CharIndex > PtrSize(BasePtr)),
  1071.             PRERR(ForceAbort,"TextViewCalculateColumnFromCharIndex char range exceeded"));
  1072.         TargetIndex = 0;
  1073.         for (CharScan = 0; CharScan < CharIndex; CharScan += 1)
  1074.             {
  1075.                 if (BasePtr[CharScan] == 0x09)
  1076.                     {
  1077.                         TargetIndex += View->SpacesPerTab
  1078.                             - (TargetIndex % View->SpacesPerTab);
  1079.                     }
  1080.                  else
  1081.                     {
  1082.                         TargetIndex += 1;
  1083.                     }
  1084.             }
  1085.         return TargetIndex;
  1086.     }
  1087.  
  1088.  
  1089. /* put a new line of data in.  data on the old line is replaced */
  1090. MyBoolean                    SetTextViewLine(TextViewRec* View, long LineIndex, char* LineToCopy)
  1091.     {
  1092.         MyBoolean                ReturnValue;
  1093.  
  1094.         CheckPtrExistence(View);
  1095.         ReturnValue = TextStorageChangeLine(View->Storage,LineIndex,LineToCopy);
  1096.         if ((View->SelectStartLine == LineIndex) && (View->SelectStartChar
  1097.         > TextStorageGetLineLength(View->Storage,LineIndex)))
  1098.             {
  1099.                 View->SelectStartChar = TextStorageGetLineLength(View->Storage,LineIndex);
  1100.             }
  1101.         if ((View->SelectEndLine == LineIndex) && (View->SelectEndCharPlusOne
  1102.             > TextStorageGetLineLength(View->Storage,LineIndex)))
  1103.             {
  1104.                 View->SelectEndCharPlusOne = TextStorageGetLineLength(View->Storage,
  1105.                     LineIndex);
  1106.             }
  1107.         TextViewRedrawLine(View,LineIndex);
  1108.         return ReturnValue;
  1109.     }
  1110.  
  1111.  
  1112. /* get a copy of the selected area */
  1113. TextStorageRec*        TextViewGetSelection(TextViewRec* View)
  1114.     {
  1115.         CheckPtrExistence(View);
  1116.         return TextStorageExtractSection(View->Storage,View->SelectStartLine,
  1117.             View->SelectStartChar,View->SelectEndLine,View->SelectEndCharPlusOne);
  1118.     }
  1119.  
  1120.  
  1121. /* delete the selection.  if this fails, the selection may have been partially */
  1122. /* deleted */
  1123. MyBoolean                    TextViewDeleteSelection(TextViewRec* View)
  1124.     {
  1125.         MyBoolean                ReturnValue;
  1126.  
  1127.         CheckPtrExistence(View);
  1128.         ReturnValue = TextStorageDeleteSection(View->Storage,View->SelectStartLine,
  1129.             View->SelectStartChar,View->SelectEndLine,View->SelectEndCharPlusOne);
  1130.         View->SelectEndLine = View->SelectStartLine;
  1131.         View->SelectEndCharPlusOne = View->SelectStartChar;
  1132.         TextViewFullRedraw(View);
  1133.         return ReturnValue;
  1134.     }
  1135.  
  1136.  
  1137. /* insert a new block of data at the insertion point, deleting any existing */
  1138. /* selection first.  if this fails, the block may have been partially inserted */
  1139. MyBoolean                    TextViewInsertBlock(TextViewRec* View, struct TextStorageRec* Data)
  1140.     {
  1141.         MyBoolean                ReturnValue;
  1142.  
  1143.         CheckPtrExistence(View);
  1144.         if (TextViewIsThereValidSelection(View))
  1145.             {
  1146.                 TextViewDeleteSelection(View);
  1147.             }
  1148.         ReturnValue = TextStorageInsertSection(View->Storage,View->SelectStartLine,
  1149.             View->SelectStartChar,Data);
  1150.         if (ReturnValue)
  1151.             {
  1152.                 if (TextStorageGetLineCount(Data) == 1)
  1153.                     {
  1154.                         View->SelectStartChar += TextStorageGetLineLength(Data,0);
  1155.                     }
  1156.                  else
  1157.                     {
  1158.                         View->SelectStartChar = TextStorageGetLineLength(Data,
  1159.                             TextStorageGetLineCount(Data) - 1);
  1160.                     }
  1161.                 View->SelectStartLine += TextStorageGetLineCount(Data) - 1;
  1162.                 View->SelectEndCharPlusOne = View->SelectStartChar;
  1163.                 View->SelectEndLine = View->SelectStartLine;
  1164.             }
  1165.         TextViewFullRedraw(View);
  1166.         return ReturnValue;
  1167.     }
  1168.  
  1169.  
  1170. /* convert the text view box into a packed buffer of lines. */
  1171. char*                            TextViewGetRawData(TextViewRec* View, char* EOLN)
  1172.     {
  1173.         CheckPtrExistence(View);
  1174.         return TextStorageMakeRawBuffer(View->Storage,EOLN);
  1175.     }
  1176.  
  1177.  
  1178. /* delete the old data in the text view object and replace it with the */
  1179. /* specified block of data */
  1180. MyBoolean                    TextViewNewRawData(TextViewRec* View, char* EOLN, char* RawData)
  1181.     {
  1182.         TextStorageRec*            Temp;
  1183.  
  1184.         CheckPtrExistence(View);
  1185.         Temp = TextStorageFromRawBuffer(RawData,EOLN);
  1186.         if (Temp == NIL)
  1187.             {
  1188.                 return False;
  1189.             }
  1190.         DisposeTextStorage(View->Storage);
  1191.         View->Storage = Temp;
  1192.         View->SelectStartLine = 0;
  1193.         View->SelectStartChar = 0;
  1194.         View->SelectEndLine = 0;
  1195.         View->SelectEndCharPlusOne = 0;
  1196.         TextViewFullRedraw(View);
  1197.         return True;
  1198.     }
  1199.  
  1200.  
  1201. /* write the data to a file.  returns True if successful */
  1202. MyBoolean                    TextViewWriteDataToFile(TextViewRec* View,
  1203.                                         struct FileType* FileRefNum, char* EOLN)
  1204.     {
  1205.         CheckPtrExistence(View);
  1206.         return TextStorageWriteDataToFile(View->Storage,FileRefNum,EOLN);
  1207.     }
  1208.